﻿using DocumentFormat.OpenXml.Wordprocessing;
using Ricebird.Wordprocessing.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Ricebird.Wordprocessing
{
    /// <summary>
    /// 样式集 - 包含段落样式和文字样式
    /// </summary>
    public class WordStyles
    {
        protected WordDocument Document
        {
            get;
            set;
        }

        public string Name
        {
            get;set;
        }

        internal WordStyles(string name, WordDocument doc)
        {
            Name = name;
            Document = doc;
            InitializeElement();
        }

        private WordStyles(string name, Style internalStyle, WordDocument doc)
        {
            Name = name;
            Document = doc;

            ParagraphStyle = internalStyle;
            ParagraphStyle.StyleParagraphProperties = ParagraphStyle.StyleParagraphProperties ?? new StyleParagraphProperties();
            ParagraphStyle.StyleRunProperties = ParagraphStyle.StyleRunProperties ?? new StyleRunProperties();
            Document.SaveStyle(ParagraphStyle);
        }

        public void InitializeElement()
        {
            ParagraphStyle = Document.GetStyleFromDocument(e => e.StyleName?.Val == Name);
            if (ParagraphStyle == null)
            {
                string paraId = Guid.NewGuid().ToString("N");
                ParagraphStyle = new Style()
                {
                    CustomStyle = true,
                    Type = StyleValues.Paragraph,
                    StyleName = new StyleName()
                    {
                        Val = Name
                    },
                    StyleId = paraId,
                    StyleParagraphProperties = new StyleParagraphProperties(),
                    StyleRunProperties = new StyleRunProperties()
                };
            }

            ParagraphStyle.StyleParagraphProperties = ParagraphStyle.StyleParagraphProperties ?? new StyleParagraphProperties();
            ParagraphStyle.StyleRunProperties = ParagraphStyle.StyleRunProperties ?? new StyleRunProperties();
            Document.SaveStyle(ParagraphStyle);
        } // InitializeElement

        internal Style ParagraphStyle
        {
            get;set;
        }

        internal ParagraphStyleId ParagraphStyleId => new ParagraphStyleId()
        {
            Val = ParagraphStyle.StyleId
        };

        internal RunStyle RunStyleId => new RunStyle()
        {
            Val = ParagraphStyle.StyleId
        };

        public WordStyles CloneStyle(string newName)
        {
            var style = (Style)ParagraphStyle.CloneNode(true);
            style.StyleName = new StyleName()
            {
                Val = newName
            };
            style.StyleId = Guid.NewGuid().ToString("N");
            style.BasedOn = new BasedOn()
            {
                Val = ParagraphStyle.StyleId
            };
            WordStyles newStyle = new WordStyles(newName, style, Document);
            return newStyle;
        }

        #region 设置样式
        /// <summary>
        /// 设置字体
        /// </summary>
        /// <param name="family">字体</param>
        public WordStyles SetFontFamily(string family)
        {
            return SetFontFamily(family, family);
        }

        /// <summary>
        /// 设置字体
        /// </summary>
        /// <param name="zwFamily">中文字体</param>
        /// <param name="asciiFamily">西文字体</param>
        public WordStyles SetFontFamily(string zwFamily, string asciiFamily)
        {
            ParagraphStyle.StyleRunProperties.RunFonts = new RunFonts()
            {
                Ascii = asciiFamily,
                EastAsia = zwFamily
            };
            return this;
        }

        /// <summary>
        /// 设置字号
        /// </summary>
        /// <param name="sizePoint">单位：点</param>
        public WordStyles SetFontSize(int sizePoint)
        {
            if (sizePoint < 0 || sizePoint > 800)
            {
                throw new InvalidOperationException("字体大小必须大于0，并且小于800");
            }

            ParagraphStyle.StyleRunProperties.FontSize = new DocumentFormat.OpenXml.Wordprocessing.FontSize()
            {
                Val = (sizePoint * 2).ToString()
            };
            return this;
        }

        /// <summary>
        /// 设置字号
        /// </summary>
        /// <param name="size">单位：字号</param>
        public WordStyles SetFontSize(FontSize size)
        {
            int sz = (int)size;
            ParagraphStyle.StyleRunProperties.FontSize = new DocumentFormat.OpenXml.Wordprocessing.FontSize()
            {
                Val = sz.ToString()
            };
            return this;
        }

        /// <summary>
        /// 设置粗体
        /// </summary>
        /// <param name="isBold">设置为false为取消</param>
        public WordStyles SetBold(bool isBold = true)
        {
            ParagraphStyle.StyleRunProperties.Bold = new Bold()
            {
                Val = isBold
            };
            return this;
        }

        /// <summary>
        /// 设置斜体
        /// </summary>
        /// <param name="isItalic">设置为false为取消</param>
        public WordStyles SetItalic(bool isItalic = true)
        {
            ParagraphStyle.StyleRunProperties.Italic = new Italic()
            {
                Val = isItalic
            };
            return this;
        }

        /// <summary>
        /// 设置下划线
        /// </summary>
        /// <param name="isUnderline">设置为false为取消</param>
        /// <param name="lineStyle">设置下划线样式</param>
        public WordStyles SetUnderline(UnderlineStyle lineStyle = UnderlineStyle.Single)
        {
            UnderlineValues value = (UnderlineValues)Enum.Parse(typeof(UnderlineValues), lineStyle.ToString());
            ParagraphStyle.StyleRunProperties.Underline = new Underline()
            {
                Val = value
            };
            return this;
        }

        /// <summary>
        /// 设置文字对齐
        /// </summary>
        /// <param name="align">对齐方式，默认左对齐</param>
        public WordStyles SetAlign(TextAlign align = TextAlign.Left)
        {
            JustificationValues value = (JustificationValues)Enum.Parse(typeof(JustificationValues), align.ToString());
            ParagraphStyle.StyleParagraphProperties.Justification = new Justification()
            {
                Val = value
            };

            return this;
        }

        /// <summary>
        /// 设置首行缩进
        /// </summary>
        /// <param name="chars">字符数</param>
        public WordStyles SetFirstLineIndent(double chars = 2)
        {
            if (chars < 0)
            {
                throw new InvalidOperationException("参数chars必须大于 0");
            }

            ParagraphStyle.StyleParagraphProperties.Indentation = ParagraphStyle.StyleParagraphProperties.Indentation ?? new Indentation();
            ParagraphStyle.StyleParagraphProperties.Indentation.FirstLineChars = (int)(chars * 100);
            return this;
        }

        /// <summary>
        /// 设置左侧缩进字符
        /// </summary>
        /// <param name="chars"></param>
        /// <returns></returns>
        public WordStyles SetLeftChars(double chars = 0)
        {
            if (chars < 0)
            {
                throw new InvalidOperationException("参数chars必须大于 0");
            }

            ParagraphStyle.StyleParagraphProperties.Indentation = ParagraphStyle.StyleParagraphProperties.Indentation ?? new Indentation();
            ParagraphStyle.StyleParagraphProperties.Indentation.LeftChars = (int)(chars * 100);
            return this;
        }

        /// <summary>
        /// 设置右侧缩进字符
        /// </summary>
        /// <param name="chars"></param>
        /// <returns></returns>
        public WordStyles SetRightChars(double chars = 0)
        {
            if (chars < 0)
            {
                throw new InvalidOperationException("参数chars必须大于 0");
            }

            ParagraphStyle.StyleParagraphProperties.Indentation = ParagraphStyle.StyleParagraphProperties.Indentation ?? new Indentation();
            ParagraphStyle.StyleParagraphProperties.Indentation.RightChars = (int)(chars * 100);
            return this;
        }

        /// <summary>
        /// 设置行高
        /// </summary>
        /// <param name="times">单位：倍数</param>
        public WordStyles SetLineSpacing(double times)
        {
            var sbl = ParagraphStyle.StyleParagraphProperties.SpacingBetweenLines;
            if (sbl == null)
            {
                sbl = new SpacingBetweenLines();
                ParagraphStyle.StyleParagraphProperties.SpacingBetweenLines = sbl;
            }
            sbl.Line = (times * 240).ToString();
            return this;
        }

        /// <summary>
        /// 设置段前间距
        /// </summary>
        /// <param name="pt">单位：磅</param>
        public WordStyles SpaceingBefore(int pt)
        {
            var sbl = ParagraphStyle.StyleParagraphProperties.SpacingBetweenLines;
            if (sbl == null)
            {
                sbl = new SpacingBetweenLines();
                ParagraphStyle.StyleParagraphProperties.SpacingBetweenLines = sbl;
            }
            sbl.Before = (pt * 20).ToString();
            return this;
        }

        /// <summary>
        /// 设置段后间距
        /// </summary>
        /// <param name="pt">单位：磅</param>
        public WordStyles SpacingAfter(int pt)
        {
            var sbl = ParagraphStyle.StyleParagraphProperties.SpacingBetweenLines;
            if (sbl == null)
            {
                sbl = new SpacingBetweenLines();
                ParagraphStyle.StyleParagraphProperties.SpacingBetweenLines = sbl;
            }
            sbl.After = (pt * 20).ToString();
            return this;
        }

        /// <summary>
        /// 该样式集在Word程序里显示
        /// </summary>
        /// <returns></returns>
        public WordStyles ShowOnUi()
        {
            ParagraphStyle.PrimaryStyle = new PrimaryStyle();
            return this;
        }

        /// <summary>
        /// 该样式集不在Word程序里显示
        /// </summary>
        /// <returns></returns>
        public WordStyles HideOnUi()
        {
            ParagraphStyle.PrimaryStyle = null;
            return this;
        }

        /// <summary>
        /// 设置下一段的样式
        /// </summary>
        /// <param name="styleId">如果不填，则设置为正文，也就是Normal样式对应的ID。</param>
        /// <returns></returns>
        public WordStyles NextTo(string styleId = "")
        {
            if (string.IsNullOrWhiteSpace(styleId))
            {
                var normalStyle = Document.GetStyleFromDocument(e => e.StyleName?.Val?.Value?.ToLower() == "normal");
                styleId = normalStyle?.StyleName?.Val;
            }

            if (!string.IsNullOrWhiteSpace(styleId))
            {
                ParagraphStyle.NextParagraphStyle = new NextParagraphStyle()
                {
                    Val = styleId
                };
            }
            else
            {
                ParagraphStyle.NextParagraphStyle = null;
            }

            return this;
        }

        /// <summary>
        /// 将该样式设置为默认样式
        /// </summary>
        /// <returns></returns>
        internal WordStyles SetDefault()
        {
            ParagraphStyle.Default = true;
            return this;
        }
        #endregion
    }
}
